package com.yuanchu.marketing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.marketing.client.FeignStoreClient;
import com.yuanchu.marketing.dao.YoshopCouponDao;
import com.yuanchu.marketing.dao.YoshopUserCouponDao;
import com.yuanchu.marketing.dto.CouponParamsDto;
import com.yuanchu.marketing.dto.CouponReceiveDto;
import com.yuanchu.marketing.entity.YoshopCouponEntity;
import com.yuanchu.marketing.entity.YoshopUserCouponEntity;
import com.yuanchu.marketing.service.YoshopCouponService;
import com.yuanchu.marketing.service.YoshopUserCouponService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.yuanchu.common.utils.DateFormatUtils.convertStringToSeconds;


@Service("yoshopCouponService")
public class YoshopCouponServiceImpl extends ServiceImpl<YoshopCouponDao, YoshopCouponEntity> implements YoshopCouponService {

    @Resource
    private YoshopUserCouponDao userCouponDao;
    @Resource
    private YoshopUserCouponService userCouponService;
    @Resource
    private FeignStoreClient feignStoreClient;

    @Override
    public YoshopCouponEntity queryCouponById(Integer couponId) {
        return this.getById(couponId);
    }

    @Override
    public List<YoshopCouponEntity> queryCouponList(Integer userId) {
        LambdaQueryWrapper<YoshopCouponEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopCouponEntity::getIsDelete, 0);
        lqw.eq(YoshopCouponEntity::getStatus, 1);
        lqw.orderByDesc(YoshopCouponEntity::getCreateTime);
        List<YoshopCouponEntity> couponEntityList = this.list(lqw);
        List<Integer> couponIds;
        if (userId != null){
            couponIds = userCouponDao.selectUserCouponId(userId);
        } else {
            couponIds = Collections.emptyList();
        }
        for (YoshopCouponEntity couponEntity : couponEntityList) {
            if (couponIds.contains(couponEntity.getCouponId())){
                Map<String, Object> state = new HashMap<>();
                state.put("text", "已领取");
                state.put("value", 0);
                couponEntity.setState(state);
            }else{
                Map<String, Object> state = new HashMap<>();
                state.put("text", "领取");
                state.put("value", 1);
                couponEntity.setState(state);
            }
            couponEntity.setStartTime(DateFormatUtils.formatDatetimeFormat(couponEntity.getStartTime()));
            couponEntity.setEndTime(DateFormatUtils.formatDatetimeFormat(couponEntity.getEndTime()));
        }
        return couponEntityList;
    }

    @Override
    public PageResult<YoshopCouponEntity> queryCouponAll(Integer page, String search) {
        LambdaQueryWrapper<YoshopCouponEntity> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotEmpty(search), YoshopCouponEntity::getName, search);
        lqw.orderByDesc(YoshopCouponEntity::getSort);
        Page<YoshopCouponEntity> couponEntityPage = this.page(new Page<>(page, 15), lqw);
        List<YoshopCouponEntity> couponEntityList = couponEntityPage.getRecords();

        for (YoshopCouponEntity couponEntity : couponEntityList) {
            couponEntity.setStartTime(DateFormatUtils.formatDatetimeFormat(couponEntity.getStartTime()));
            couponEntity.setEndTime(DateFormatUtils.formatDatetimeFormat(couponEntity.getEndTime()));
        }
        return PageResult.formatPageResult(couponEntityList, page, 15, couponEntityPage.getTotal());

    }

    @Override
    @Transactional
    public void editCoupon(CouponParamsDto params) {
        YoshopCouponEntity form = params.getForm();
        YoshopCouponEntity coupon = this.getById(params.getCouponId());
        if (coupon == null){
            throw new YuanChuException("优惠券不存在");
        }
        BeanUtils.copyProperties(form, coupon);
        coupon.setCouponId(params.getCouponId());
        Integer expireType = form.getExpireType();
        if (expireType == 20){
            List<String> betweenTime = form.getBetweenTime();
            DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
            long startTime = ZonedDateTime.parse(betweenTime.get(0), formatter).toInstant().toEpochMilli();
            long endTime =  ZonedDateTime.parse(betweenTime.get(1), formatter).toInstant().toEpochMilli();
            coupon.setStartTime(String.valueOf(startTime));
            coupon.setEndTime(String.valueOf(endTime));
        }

        coupon.setUpdateTime(String.valueOf(Instant.now().toEpochMilli()/1000));
        boolean update = this.updateById(coupon);
        if (!update){
            throw new YuanChuException("优惠券编辑失败");
        }
    }

    @Override
    public void addCoupon(CouponParamsDto params) {
        YoshopCouponEntity form = params.getForm();
        YoshopCouponEntity coupon = new YoshopCouponEntity();
        BeanUtils.copyProperties(form, coupon);
        Integer expireType = coupon.getExpireType();
        if (expireType == 20){
            List<String> betweenTime = form.getBetweenTime();
            DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
            long startTime = ZonedDateTime.parse(betweenTime.get(0), formatter).toInstant().toEpochMilli();
            long endTime =  ZonedDateTime.parse(betweenTime.get(1), formatter).toInstant().toEpochMilli();
            coupon.setStartTime(String.valueOf(startTime));
            coupon.setEndTime(String.valueOf(endTime));
        }
        coupon.setCreateTime(String.valueOf(Instant.now().toEpochMilli()/1000));
        coupon.setUpdateTime(String.valueOf(Instant.now().toEpochMilli()/1000));
        boolean save = this.save(coupon);
        if (!save){
            throw new YuanChuException("优惠券添加失败");
        }

    }

    @Override
    public PageResult<YoshopUserCouponEntity> queryCouponReceive(CouponReceiveDto params) {
        LambdaQueryWrapper<YoshopUserCouponEntity> lqw = new LambdaQueryWrapper<>();
        if (params.getBetweenTimeStart() != null && params.getBetweenTimeEnd() != null){
            long start = convertStringToSeconds(params.getBetweenTimeStart());
            long end = convertStringToSeconds(params.getBetweenTimeEnd());
            lqw.between(YoshopUserCouponEntity::getCreateTime, start, end);
        }
        lqw.orderByDesc(YoshopUserCouponEntity::getCreateTime);
        Page<YoshopUserCouponEntity> userCouponPage = userCouponDao.selectPage(new Page<>(params.getPage(), params.getPageSize()), lqw);
        List<YoshopUserCouponEntity> userCouponList = userCouponPage.getRecords();
        for (YoshopUserCouponEntity userCouponEntity : userCouponList) {
            userCouponEntity.setCreateTime(DateFormatUtils.formatDatetimeFormat(userCouponEntity.getCreateTime()));
            userCouponEntity.setUpdateTime(DateFormatUtils.formatDatetimeFormat(userCouponEntity.getUpdateTime()));
            userCouponEntity.setUser(feignStoreClient.queryUserByUserId(userCouponEntity.getUserId()));
            if (userCouponEntity.getExpireType() == 20){
                userCouponEntity.setEndTime(DateFormatUtils.formatDatetimeFormat(userCouponEntity.getEndTime()));
                userCouponEntity.setStartTime(DateFormatUtils.formatDatetimeFormat(userCouponEntity.getStartTime()));
            }
        }
        if(StringUtils.isNotEmpty(params.getCouponName())){
            userCouponList = userCouponList.stream().filter(userCouponEntity -> userCouponEntity.getName().contains(params.getCouponName())).collect(Collectors.toList());
        }
        if (StringUtils.isNotEmpty(params.getNickName())){
            userCouponList = userCouponList.stream().filter(userCouponEntity -> userCouponEntity.getUser().getNickName().contains(params.getNickName())).collect(Collectors.toList());
        }

        return PageResult.formatPageResult(userCouponList, params.getPage(), params.getPageSize(), userCouponPage.getTotal());
    }


}